package com.erpoa.utils;

import java.util.HashSet;
import java.util.Set;

public class EnhanceThreadLocal<T> extends ThreadLocal<T> {

    // 管理所有的EnhanceThreadLocal
    private static ThreadLocal<Set<EnhanceThreadLocal<?>>> local = new ThreadLocal<Set<EnhanceThreadLocal<?>>>();

    @Override
    public void set(T value) {
        super.set(value);

        Set<EnhanceThreadLocal<?>> set = local.get();
        if (set == null) {
            synchronized (local) {
                set = local.get();
                if (set == null) {
                    set = new HashSet<EnhanceThreadLocal<?>>();
                    local.set(set);
                }
            }
        }

        synchronized (set) {
            set.add(this);
        }
    }

    @Override
    public void remove() {
        remove(true);
    }

    /**
     * @param isRemoveFSet 当为true时,系统在会同时删除set中的删除该元素，如果在foreach中删除会引起异常
     *                     所以在foreach中调用此方法时，isRemoveFSet要设置为false
     */
    protected final void remove(boolean isRemoveFSet) {
        super.remove();

        if (isRemoveFSet) {
            Set<EnhanceThreadLocal<?>> localSet = local.get();
            if (localSet != null) {
                synchronized (localSet) {
                    localSet.remove(this);
                }
            }
        }
    }

    public static int size() {
        Set<EnhanceThreadLocal<?>> localSet = local.get();
        if (localSet == null) {
            return 0;
        }
        return localSet.size();
    }

    public static void clean() {
        Set<EnhanceThreadLocal<?>> localSet = local.get();
        if (localSet != null) {
            synchronized (localSet) {
                for (EnhanceThreadLocal<?> etl : localSet) {
                    etl.remove(false);
                }
                localSet.clear();
            }
        }
        local.remove();
    }
}
